class SimpleSlider extends egret.DisplayObjectContainer {
    private _value: number;
    private _max: number = 100;
    private _min: number = 0;

    private _handle: egret.Shape;
    private _back: egret.Shape;

    private dragging: boolean = false

    private _backWidth: number = 4;
    private _backHeight: number = 100;
    private _backColor: number = 0xcccccc;
    private _backBorderColor: number = 0x999999;
    private _backRadius: number = 2;

    private _handleWidth: number = 16;
    private _handleHeight: number = 6;
    private _handleColor: number = 0xeeeeee;
    private _handleBorderColor: number = 0xcccccc;
    private _handleRadius: number = 2;


    public constructor(min: number = 0, max: number = 100, value: number = 100) {
        super()
        this._min = min;
        this._max = max;
        this._value = Math.min(Math.max(value, min), max)
        this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this)
    }

    private onAddToStage() {
        this._back = new egret.Shape();
        this.addChild(this._back);

        this._handle = new egret.Shape();
        this.addChild(this._handle);

        this.stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onTouchBegin, this)

        this.draw()
        this.updatePosition()
    }

    private draw() {
        this.drawBack()
        this.drawHandle()
    }

    private drawBack() {
        this._back.graphics.clear()
        this._back.graphics.beginFill(this._backColor)
        this._back.graphics.lineStyle(0, this._backBorderColor)
        this._back.graphics.drawRoundRect(0, 0, this._backWidth, this._backHeight, this._backRadius, this._backRadius)
        this._back.graphics.endFill()
        this._back.x = this._handleWidth / 2 - this._backWidth / 2
    }

    private drawHandle() {
        this._handle.graphics.clear();
        this._handle.graphics.beginFill(this._handleColor);
        this._handle.graphics.lineStyle(0, this._handleBorderColor);
        this._handle.graphics.drawRoundRect(0, 0, this._handleWidth, this._handleHeight, this._handleRadius, this._handleRadius);
        this._handle.graphics.endFill();
    }

    private updatePosition(): void {
        let handleRange: number = this._backHeight - this._handleHeight;
        let valueRange: number = this._max - this._min;
        this._handle.y = handleRange - (this._value - this._min) / valueRange * handleRange;
    }

    private updateValue(): void {
        let handleRange: number = this._backHeight - this._handleHeight;
        let valueRange: number = this._max - this._min;
        this._value = (handleRange - this._handle.y) / handleRange * valueRange + this._min;
        this.dispatchEvent(new egret.Event(egret.Event.CHANGE));
    }

    private onTouchBegin(evt: egret.TouchEvent): void {
        if (this._handle.getTransformedBounds(this.stage).contains(evt.stageX, evt.stageY)) {
            this.dragging = true
        }
        this.stage.addEventListener(egret.TouchEvent.TOUCH_END, this.onTouchEnd, this)
        this.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.onTouchMove, this)
    }

    private onTouchEnd(evt: egret.TouchEvent): void {
        this.stage.removeEventListener(egret.TouchEvent.TOUCH_END, this.onTouchEnd, this)
        this.stage.removeEventListener(egret.TouchEvent.TOUCH_MOVE, this.onTouchMove, this)
        this.dragging = false
    }

    private onTouchMove(evt: egret.TouchEvent): void {
        if (this._handle.getTransformedBounds(this.stage).contains(evt.stageX, evt.stageY)) {
            this.dragging = true
        }

        if (this.dragging) {
            let posY = evt.stageY - this.y
            this._handle.y = Math.min(this._backHeight - this._handleHeight, Math.max(posY, 0))
            this.updateValue()
        }
    }

    public set value(n: number) {
        this._value = n;
        this._value = Math.min(this._max, Math.max(this._value, this._min));
        this.updatePosition();
    }

    public get value(): number {
        return this._value;
    }
}